#!/usr/bin/python
# -*- coding: utf-8 -*-

# Created: Mars 2010	by: Alexandre PLANCHON

from PyQt4 import QtCore, QtGui	# Bibliothèques graphiques
from PythonUI.Ui_PageEnvironnement import Ui_PageEnvironnement #Cette page hérite du fichier généré par pyuic4
import os			# Pour lancer des commandes dans un terminal
import sys			# Appels de fonctions systèmes
from iwlist2 import IwList	# Pour parser les résultats du scan.
from iwconfig import IwCfg	# Pour vérifier si la station est déjà connectée à un AP.
import commands			# Pour lancer la capture du traffic

globals()["x"] = 0
globals()["y"] = 0

class PageEnvironnement(Ui_PageEnvironnement,QtGui.QDialog):
    """
    Page permettant de scanner l'environnement radio.
    Liste des points d'accès sous forme d'un tableau avec possibilité de capturer le traffic
    """        

    def __init__(self,session):
        """
        Fonction d'initialisation
        """
        self.app = QtGui.QApplication(sys.argv)
        QtGui.QDialog.__init__(self)
        self.session=session
        self.list=[]
        self.filename = ""
        self.Connecte=False
        self.Liste= IwList("un")
        self.PremierScan=True

    def affich(self,param):
        """
        Fonction permettant a cette page d'etre appelée directement par Main.py
        en entrant "./Main.py Env"
        """
        self.parametre=param
        self.setupUi(self)
        self.show()
        sys.exit(self.app.exec_())

    def ScanAP(self):
        """
        Fonction appelee lors de l'appui sur Scanner
        Lance un iwlist pour scanner l'environnement puis rempli les champs de l'interface graphique
        """
        print "Scan en cours sur "+self.comboBox_Canaux.currentText()+ " ..."
        
        #On regarde si on doit supprimer l'avertissement
        if self.Connecte==True :
            AP= IwCfg("un")
            try:
                AP.iwcfg("wlan0")            
            except IndexError:
                AP.result["ESSID"]=""
                self.label_Connecte.setVisible(False)
                self.Connecte=False     
        #On vide la ComboBox
        self.comboBox_Traffic.clear()
        
        #On vide dictionnaire
        self.Liste.dico={}
        self.Liste.su=[]
        self.Liste.u=""
        self.Liste.listdico=[]
        self.Liste.regex=""
        self.Liste.result_regex=""
    	self.Liste.iwList('wlan0')
        
        ListeAP=""
        ListeCan=""
        ListeBSSID=""
        ListeEnc=""
        ListeQual=""
        #self.label_AP.setText("")
        #self.label_Can.setText("")
        #self.label_MAC.setText("")
        #self.label_Enc.setText("")
        #self.label_Qual.setText("")
        
        if self.Liste.listdico == []:
            print "Aucun AP trouvé"
            self.label_Erreur.setVisible(True)
        else:
            self.label_Erreur.setVisible(False)
            self.label_TitreAP.setVisible(True)
	    self.label_TitreCanal.setVisible(True)
	    self.label_TitreEncryption.setVisible(True)
	    self.label_TitreMAC.setVisible(True)
            self.label_AP.setVisible(True)
	    self.label_Can.setVisible(True)
	    self.label_Enc.setVisible(True)
	    self.label_MAC.setVisible(True)  
            self.label_TitreQualite.setVisible(True)  
            self.label_Qual.setVisible(True)
            self.pushButton_Capture.setEnabled(True)
            self.pushButton_ScanAP.setText("Actualiser")
            for element in sorted(self.Liste.listdico, key=tri):                
                if (element["Channel"] == self.comboBox_Canaux.currentText() or self.comboBox_Canaux.currentText() == "Tous les canaux") and not (not self.checkWEP.isChecked() and (element["Encryption key"]=="on" and element["crypto"]=="Unknown")) and not (not self.checkOpen.isChecked() and element["Encryption key"]=="off")  and not (not self.checkWPA.isChecked() and (element["Encryption key"]=="on" and element["crypto"]=="WPA")):
                    ListeAP = ListeAP + element["ESSID"].replace('"','') + "\n"
                    ListeCan= ListeCan+ element["Channel"] + "\n"
                    ListeBSSID= ListeBSSID+ element["Address"] + "\n"
                    if element["Encryption key"]=="off":
                        ListeEnc= ListeEnc+ "OFF" + "\n"
                    #if element["Encryption key"]=="on" and element["crypto"]=="WEP" :
                    #    ListeEnc= ListeEnc+ "WEP" + "\n"
                    if element["Encryption key"]=="on" and element["crypto"]=="WPA" :
                        ListeEnc= ListeEnc+ "WPA" + "\n"
                    #if element["Encryption key"]=="on" and element["crypto"]=="WPA2" :
                    #    ListeEnc= ListeEnc+ "WPA2" + "\n"
                    if element["Encryption key"]=="on" and element["crypto"]=="Unknown" :
                        ListeEnc= ListeEnc+ "WEP" + "\n"
                    ListeQual=ListeQual + element["Quality"] + "\n"
                    self.comboBox_Traffic.addItem(element["Address"])
            self.label_AP.setText(ListeAP)
            self.label_Can.setText(ListeCan)
            self.label_MAC.setText(ListeBSSID)
            self.label_Enc.setText(ListeEnc)
            self.label_Qual.setText(ListeQual)

    def suivant(self):   
        """
        Fonction appelee lors de l'appui sur OK.
        Lance Page2.py        
        """
        self.close()
        os.system("./Main.py 2")

    def Capture(self):
        """
        Fonction appelee lors de l'appui sur Capturer.
        Lance airodump-ng ciblé sur le BSSID précisé        
        """
        #On récupère le canal du BSSID selectionné pour cibler la capture
        for element in sorted(self.Liste.listdico):
            if element["Address"] == self.comboBox_Traffic.currentText():
                canal=element["Channel"]
        print "Démarrage d'airodump..."        
        if self.PremierScan==True:
            QtGui.QMessageBox.information(self, "Infos", "La capture sera enregistree sous Capture-xx.cap dans le dossier de l'utilisateur\nCtrl+C pour arreter la capture", QtGui.QMessageBox.Ok)
            commands.getoutput('gksudo airmon-ng start wlan0')
            self.PremierScan=False
        commands.getoutput(str("gksudo -k \"xterm -e airodump-ng mon0 -w /$HOME/Capture --output-format pcap --bssid " + self.comboBox_Traffic.currentText() +" -c" + canal +"\""))        

    def setupUi(self, Dialog):
        """
        Definition de l'interface graphique.
        Definition des signaux générés par chaque bouton.
        Masquage de certains éléments de l'UI.
        """        
        Ui_PageEnvironnement.setupUi(self,Dialog)                 
        self.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), self.suivant)
        self.connect(self.pushButton_ScanAP, QtCore.SIGNAL("clicked()"), self.ScanAP)
        self.connect(self.pushButton_Capture, QtCore.SIGNAL("clicked()"), self.Capture)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
        self.label_TitreAP.setVisible(False)
	self.label_TitreCanal.setVisible(False)
	self.label_TitreEncryption.setVisible(False)
	self.label_TitreMAC.setVisible(False)
        self.label_AP.setVisible(False)
	self.label_Can.setVisible(False)
	self.label_Enc.setVisible(False)
	self.label_MAC.setVisible(False)
        self.label_TitreQualite.setVisible(False)
        self.label_Qual.setVisible(False)
        self.label_Erreur.setVisible(False)
        
        AP= IwCfg("un")
        try:
            AP.iwcfg("wlan0")
            self.label_Connecte.setText("Vous etes actuellement connecte a "+AP.result["ESSID"]+"\nPour un fonctionnement optimal du scan, merci de vous deconnecter")
            self.Connecte=True
        except IndexError:
            AP.result["ESSID"]=""
	 
def tri(dic):
    """
    Fonction permettant de trier un dictionnaire selon les index précisés 
    """
    return dic.get("ESSID", "") + dic.get("Channel", "")
